package top.yongyan0624.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import top.yongyan0624.Utils.RedisUtil;
import top.yongyan0624.entity.Count;
import top.yongyan0624.entity.Message;
import top.yongyan0624.mapper.CountMapper;
import top.yongyan0624.service.CountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.yongyan0624.service.MessageService;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yongyan
 * @since 2021-05-19
 */
@Service
public class CountServiceImpl extends ServiceImpl<CountMapper, Count> implements CountService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private MessageService messageService;

    @Override
    public void setCount(Count count) {
        int sum = 0;
        if (redisUtil.hasKey("count:" + count.getMsgId())) {
            //如果有点赞总数缓存，获取点赞总数
            sum = (int) redisUtil.get("count:" + count.getMsgId());
        } else {
            //若没有，初始化点赞总数
            redisUtil.set("count:" + count.getMsgId(), sum);
        }

        if (count.getStatus()) {
            redisUtil.set("count:" + count.getMsgId(), sum + 1);
        } else {
            redisUtil.set("count:" + count.getMsgId(), sum - 1);
        }

        redisUtil.set("countMsg:" + count.getMsgId() + ":" + count.getUserId() + ":" + count.getPostId(), count.getStatus());

    }

    @Override
    public void handleCache(Count count) {
        if (redisUtil.hasKey("countMsg:" + count.getMsgId() + ":" + count.getUserId() + ":" + count.getPostId())) {
            //若有点赞信息缓存，直接使用
            count.setStatus((Boolean) redisUtil.get("countMsg:" + count.getMsgId() + ":" + count.getUserId() + ":" + count.getPostId()));
        } else {
            //若没有缓存,做缓存
            redisUtil.set("countMsg:" + count.getMsgId() + ":" + count.getUserId() + ":" + count.getPostId(), count.getStatus());
        }
    }

    @Override
    @Transactional
    public void transCountFromRedis() {
        Set<String> keys = redisTemplate.keys("count:*");
        for (String key : keys) {
            //获取留言id
            String[] split = key.split(":");
            long msgId = Long.parseLong(split[1]);
            //通过留言id查找到留言记录
            Message msg = messageService.getById(msgId);
            if (null != msg){
                //读取缓存
                msg.setCount((Integer) redisUtil.get(key));
                //更新留言的点赞数，使之持久化
                messageService.updateById(msg);
            }
        }
    }

    @Override
    @Transactional
    public void transCountInfoFromRedis() {
        Set<String> keys = redisTemplate.keys("countMsg:*");
        for (String key : keys) {
            //获取点赞信息
            String[] split = key.split(":");
            //封装点赞信息
            long msgId = Long.parseLong(split[1]);
            long userId = Long.parseLong(split[2]);
            long postId = Long.parseLong(split[3]);
            //通过这三个id的唯一键，查询是已存在点赞信息
            Map<String, Object> map = new HashMap<>();
            map.put("msg_id", msgId);
            map.put("post_id", postId);
            Count count = this.getOne(new QueryWrapper<Count>().allEq(map));

            //持久化
            if (count == null) {
                //不存在重复的点赞信息，保存信息
                count = new Count();
                count.setMsgId(msgId);
                count.setUserId(userId);
                count.setPostId(postId);
                count.setStatus((Boolean) redisUtil.get(key));

                this.save(count);
            } else {
                //存在当前点赞信息，更新信息
                count.setStatus((Boolean) redisUtil.get(key));

                this.update(count, new UpdateWrapper<Count>().allEq(map));
            }
        }
    }
}
